{\small
\begin{verbatim}
title Xen 2.0 / XenLinux 2.6.9
- kernel /boot/xen.gz dom0_mem=131072
+ kernel /boot/xen.gz dom0_mem=128M
module /boot/vmlinuz-2.6.9-xen0 root=/dev/sda4 ro console=tty0
\end{verbatim}
}
\subsection{Serial Console (optional)}
-%% kernel /boot/xen.gz dom0_mem=131072 com1=115200,8n1
+%% kernel /boot/xen.gz dom0_mem=128M com1=115200,8n1
%% module /boot/vmlinuz-2.6.9-xen0 root=/dev/sda4 ro
\begin{quote}
{\small
\begin{verbatim}
- kernel /boot/xen.gz dom0_mem=131072 com1=115200,8n1
+ kernel /boot/xen.gz dom0_mem=128M com1=115200,8n1
\end{verbatim}}
-\end{quote}
+\end{quote}
This configures Xen to output on COM1 at 115,200 baud, 8 data bits,
1 stop bit and no parity. Modify these parameters for your set up.
editing \path{grub.conf}.
\begin{description}
-\item [ignorebiostables ]
- Disable parsing of BIOS-supplied tables. This may help with some
- chipsets that aren't fully supported by Xen. If you specify this
- option then ACPI tables are also ignored, and SMP support is
- disabled.
-
\item [noreboot ]
Don't reboot the machine automatically on errors. This is
useful to catch debug output if you aren't catching console messages
Disable SMP support.
This option is implied by `ignorebiostables'.
-\item [noacpi ]
- Disable ACPI tables, which confuse Xen on some chipsets.
- This option is implied by `ignorebiostables'.
-
\item [watchdog ]
Enable NMI watchdog which can report certain failures.
`nmi=dom0': Inform DOM0 of the NMI. \\
`nmi=ignore': Ignore the NMI.
+\item [mem=xxx ]
+ Set the physical RAM address limit. Any RAM appearing beyond this
+ physical address in the memory map will be ignored. This parameter
+ may be specified with a {\bf k}, {\bf m} or {\bf g} suffix. The
+ default unit, if no suffix is specified, is bytes.
+
\item [dom0\_mem=xxx ]
- Set the amount of memory (in kB) to be allocated to domain0.
+ Set the amount of memory to be allocated to domain0. This parameter
+ may be specified with a {\bf k}, {\bf m} or {\bf g} suffix. The
+ default unit, if no suffix is specified, is kilobytes.
\item [tbuf\_size=xxx ]
Set the size of the per-cpu trace buffers, in pages
Select the CPU scheduler Xen should use. The current
possibilities are `bvt' (default), `atropos' and `rrobin'.
For more information see Section~\ref{s:sched}.
-
-\item [physdev\_dom0\_hide=(xx:xx.x)(yy:yy.y)\ldots ]
-Hide selected PCI devices from domain 0 (for instance, to stop it
-taking ownership of them so that they can be driven by another
-domain). Device IDs should be given in hex format. Bridge devices do
-not need to be hidden --- they are hidden implicitly, since guest OSes
-do not need to configure them.
\end{description}
+In addition, the following platform-specific options may be specified
+on the Xen command line. Since domain 0 shares responsibility for
+booting the platform, Xen will automatically propagate these options
+to its command line.
+These options are taken from Linux's command-line syntax with
+unchanged semantics.
+
+\begin{description}
+\item [acpi=off,force,strict,ht,noirq,\ldots ]
+ Modify how Xen (and domain 0) parses the BIOS ACPI tables.
+
+\item [acpi\_skip\_timer\_override ]
+ Instruct Xen (and domain 0) to ignore timer-interrupt override
+ instructions specified by the BIOS ACPI tables.
+
+\item [noapic ]
+ Instruct Xen (and domain 0) to ignore any IOAPICs that are present in
+ the system, and instead continue to use the legacy PIC.
+
+\end{description}
\section{XenLinux Boot Options}
unsigned int opt_dom0_mem = 16000;
/* opt_noht: If true, Hyperthreading is ignored. */
int opt_noht=0;
-/* opt_noacpi: If true, ACPI tables are not parsed. */
-int opt_noacpi=0;
/* opt_nosmp: If true, secondary processors are ignored. */
int opt_nosmp=0;
/* opt_noreboot: If true, machine will need manual reset on error. */
int opt_noreboot=0;
-/* opt_ignorebiostables: If true, ACPI and MP tables are ignored. */
-/* NB. This flag implies 'nosmp' and 'noacpi'. */
-int opt_ignorebiostables=0;
/* opt_watchdog: If true, run a watchdog NMI on each processor. */
int opt_watchdog=0;
/* opt_pdb: Name of serial port for Xen pervasive debugger (and enable pdb) */
#include <xen/config.h>
#include <xen/init.h>
#include <xen/lib.h>
+#include <xen/ctype.h>
#include <xen/sched.h>
#include <xen/smp.h>
#include <xen/delay.h>
#include <asm/i387.h>
#include <asm/shadow.h>
-/* opt_dom0_mem: Kilobytes of memory allocated to domain 0. */
-static unsigned int opt_dom0_mem = 0;
-integer_unit_param("dom0_mem", opt_dom0_mem);
+/* opt_dom0_mem: memory allocated to domain 0. */
+static unsigned int opt_dom0_mem;
+static void parse_dom0_mem(char *s)
+{
+ unsigned long long bytes = memparse(s);
+ /* If no unit is specified we default to kB units, not bytes. */
+ if ( isdigit(s[strlen(s)-1]) )
+ opt_dom0_mem = (unsigned int)bytes;
+ else
+ opt_dom0_mem = (unsigned int)(bytes >> 10);
+}
+custom_param("dom0_mem", parse_dom0_mem);
static unsigned int opt_dom0_shadow = 0;
boolean_param("dom0_shadow", opt_dom0_shadow);
#include <xen/lib.h>
#include <asm/e820.h>
+/* opt_mem: Limit of physical RAM. Any RAM beyond this point is ignored. */
+unsigned long long opt_mem;
+static void parse_mem(char *s) { opt_mem = memparse(s); }
+custom_param("mem", parse_mem);
+
struct e820map e820;
static void __init add_memory_region(unsigned long long start,
#define clip_4gb() ((void)0)
#endif
+static void __init clip_mem(void)
+{
+ int i;
+
+ if ( !opt_mem )
+ return;
+
+ for ( i = 0; i < e820.nr_map; i++ )
+ {
+ if ( (e820.map[i].addr + e820.map[i].size) <= opt_mem )
+ continue;
+ printk("Truncating memory map to %lukB\n",
+ (unsigned long)(opt_mem >> 10));
+ if ( e820.map[i].addr >= opt_mem )
+ {
+ e820.nr_map = i;
+ }
+ else
+ {
+ e820.map[i].size = opt_mem - e820.map[i].addr;
+ e820.nr_map = i + 1;
+ }
+ }
+}
+
static void __init machine_specific_memory_setup(
struct e820entry *raw, int raw_nr)
{
sanitize_e820_map(raw, &nr);
(void)copy_e820_map(raw, nr);
clip_4gb();
+ clip_mem();
}
unsigned long __init init_e820(struct e820entry *raw, int raw_nr)
int opt_noht = 0;
boolean_param("noht", opt_noht);
-/* opt_noacpi: If true, ACPI tables are not parsed. */
-static int opt_noacpi = 0;
-boolean_param("noacpi", opt_noacpi);
-
-/* opt_nosmp: If true, secondary processors are ignored. */
-static int opt_nosmp = 0;
-boolean_param("nosmp", opt_nosmp);
-
-/* opt_ignorebiostables: If true, ACPI and MP tables are ignored. */
-/* NB. This flag implies 'nosmp' and 'noacpi'. */
-static int opt_ignorebiostables = 0;
-boolean_param("ignorebiostables", opt_ignorebiostables);
-
/* opt_watchdog: If true, run a watchdog NMI on each processor. */
static int opt_watchdog = 0;
boolean_param("watchdog", opt_watchdog);
+/* **** Linux config option: propagated to domain0. */
+/* "acpi=off": Sisables both ACPI table parsing and interpreter. */
+/* "acpi=force": Override the disable blacklist. */
+/* "acpi=strict": Disables out-of-spec workarounds. */
+/* "acpi=ht": Limit ACPI just to boot-time to enable HT. */
+/* "acpi=noirq": Disables ACPI interrupt routing. */
+static void parse_acpi_param(char *s);
+custom_param("acpi", parse_acpi_param);
+
+/* **** Linux config option: propagated to domain0. */
+/* acpi_skip_timer_override: Skip IRQ0 overrides. */
+extern int acpi_skip_timer_override;
+boolean_param("acpi_skip_timer_override", acpi_skip_timer_override);
+
+/* **** Linux config option: propagated to domain0. */
+/* noapic: Disable IOAPIC setup. */
+extern int skip_ioapic_setup;
+boolean_param("noapic", skip_ioapic_setup);
+
int early_boot = 1;
unsigned long xenheap_phys_end;
extern void initialize_keytable();
extern int do_timer_lists_from_pit;
-char ignore_irq13; /* set if exception 16 works */
struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1 };
#if defined(__x86_64__)
init_idle_task();
}
+int acpi_force;
+char acpi_param[10] = "";
+static void parse_acpi_param(char *s)
+{
+ /* Save the parameter so it can be propagated to domain0. */
+ strncpy(acpi_param, s, sizeof(acpi_param));
+ acpi_param[sizeof(acpi_param)-1] = '\0';
+
+ /* Interpret the parameter for use within Xen. */
+ if ( !strcmp(s, "off") )
+ {
+ disable_acpi();
+ }
+ else if ( !strcmp(s, "force") )
+ {
+ acpi_force = 1;
+ acpi_ht = 1;
+ acpi_disabled = 0;
+ }
+ else if ( !strcmp(s, "strict") )
+ {
+ acpi_strict = 1;
+ }
+ else if ( !strcmp(s, "ht") )
+ {
+ if ( !acpi_force )
+ disable_acpi();
+ acpi_ht = 1;
+ }
+ else if ( !strcmp(s, "noirq") )
+ {
+ acpi_noirq_set();
+ }
+}
+
static void __init do_initcalls(void)
{
initcall_t *call;
identify_cpu(&boot_cpu_data); /* get CPU type info */
if ( cpu_has_fxsr ) set_in_cr4(X86_CR4_OSFXSR);
if ( cpu_has_xmm ) set_in_cr4(X86_CR4_OSXMMEXCPT);
-#ifdef CONFIG_SMP
- if ( opt_ignorebiostables )
- {
- opt_nosmp = 1; /* No SMP without configuration */
- opt_noacpi = 1; /* ACPI will just confuse matters also */
- }
- else
- {
- find_smp_config();
- smp_alloc_memory(); /* trampoline which other CPUs jump at */
- }
-#endif
- paging_init(); /* not much here now, but sets up fixmap */
- if ( !opt_noacpi )
- {
- acpi_boot_table_init();
- acpi_boot_init();
- }
-#ifdef CONFIG_SMP
+
+ find_smp_config();
+
+ smp_alloc_memory();
+
+ paging_init();
+
+ acpi_boot_table_init();
+ acpi_boot_init();
+
if ( smp_found_config )
get_smp_config();
-#endif
- init_apic_mappings(); /* make APICs addressable in our pagetables. */
+
+ init_apic_mappings();
+
scheduler_init();
- init_IRQ(); /* installs simple interrupt wrappers. Starts HZ clock. */
+
+ init_IRQ();
+
trap_init();
- time_init(); /* installs software handler for HZ clock. */
+
+ time_init();
arch_init_memory();
-#ifndef CONFIG_SMP
- APIC_init_uniprocessor();
-#else
- if ( opt_nosmp )
- APIC_init_uniprocessor();
- else
- smp_boot_cpus();
- /*
- * Does loads of stuff, including kicking the local
- * APIC, and the IO APIC after other CPUs are booted.
- * Each IRQ is preferably handled by IO-APIC, but
- * fall thru to 8259A if we have to (but slower).
- */
-#endif
+ smp_boot_cpus();
__sti();
- initialize_keytable(); /* call back handling for key codes */
+ initialize_keytable();
serial_init_stage2();
check_nmi_watchdog();
-#ifdef CONFIG_PCI
- pci_init();
-#endif
do_initcalls();
-#ifdef CONFIG_SMP
wait_init_idle = cpu_online_map;
clear_bit(smp_processor_id(), &wait_init_idle);
smp_threads_ready = 1;
smp_commence(); /* Tell other CPUs that state of the world is stable. */
while ( wait_init_idle != 0 )
cpu_relax();
-#endif
watchdog_on = 1;
#ifdef __x86_64__ /* x86_32 uses low mappings when building DOM0. */
set_bit(DF_PRIVILEGED, &dom0->flags);
- /* Grab the DOM0 command line. Skip past the image name. */
+ /* Grab the DOM0 command line. */
cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL);
if ( cmdline != NULL )
{
+ static char dom0_cmdline[256];
+
+ /* Skip past the image name. */
while ( *cmdline == ' ' ) cmdline++;
if ( (cmdline = strchr(cmdline, ' ')) != NULL )
while ( *cmdline == ' ' ) cmdline++;
+
+ /* Copy the command line to a local buffer. */
+ strcpy(dom0_cmdline, cmdline);
+ cmdline = dom0_cmdline;
+
+ /* Append any extra parameters. */
+ if ( skip_ioapic_setup && !strstr(cmdline, "noapic") )
+ strcat(cmdline, " noapic");
+ if ( acpi_skip_timer_override &&
+ !strstr(cmdline, "acpi_skip_timer_override") )
+ strcat(cmdline, " acpi_skip_timer_override");
+ if ( (strlen(acpi_param) != 0) && !strstr(cmdline, "acpi=") )
+ {
+ strcat(cmdline, " acpi=");
+ strcat(cmdline, acpi_param);
+ }
}
/*
#include <mach_apic.h>
#include <mach_wakecpu.h>
-/* Cconfigured maximum number of CPUs to activate. We name the parameter
-"maxcpus" rather than max_cpus to be compatible with Linux */
+/* opt_nosmp: If true, secondary processors are ignored. */
+static int opt_nosmp = 0;
+boolean_param("nosmp", opt_nosmp);
+
+/* maxcpus: maximum number of CPUs to activate. */
static int max_cpus = -1;
integer_param("maxcpus", max_cpus);
* If we couldnt find an SMP configuration at boot time,
* get out of here now!
*/
- if (!smp_found_config) {
- printk("SMP motherboard not detected.\n");
+ if (!smp_found_config || opt_nosmp) {
io_apic_irqs = 0;
phys_cpu_present_map = physid_mask_of_physid(0);
cpu_online_map = 1;
*(unsigned int *)param->var =
simple_strtol(opt, (char **)&opt, 0);
break;
- case OPT_UINT_UNIT:
- if ( opt != NULL )
- {
- int base = 1;
- unsigned int value;
-
- value = simple_strtoul(opt, (char **)&opt, 0);
- if (*opt == 'G' || *opt == 'g') {
- base = 1024 * 1024;
- opt++;
- } if (*opt == 'M' || *opt == 'm') {
- base = 1024;
- opt++;
- } else if (*opt == 'K' || *opt == 'k')
- opt++;
- *(unsigned int *) param->var = value * base;
- }
- break;
case OPT_BOOL:
*(int *)param->var = 1;
break;
+ case OPT_CUSTOM:
+ if ( opt != NULL )
+ ((void (*)(char *))param->var)(opt);
+ break;
}
}
cmdline = opt_end;
#endif /* BITS_PER_LONG == 32 */
+unsigned long long memparse(char *s)
+{
+ unsigned long long ret = simple_strtoull(s, &s, 0);
+
+ switch (*s) {
+ case 'G': case 'g':
+ ret <<= 10;
+ case 'M': case 'm':
+ ret <<= 10;
+ case 'K': case 'k':
+ ret <<= 10;
+ }
+
+ return ret;
+}
+
/*
* Local variables:
* mode: C
#define _ASM_ACPI_H
#include <xen/config.h>
-#include <asm/system.h>
+#include <asm/system.h> /* defines cmpxchg */
#define COMPILER_DEPENDENT_INT64 long long
#define COMPILER_DEPENDENT_UINT64 unsigned long long
#define ACPI_ASM_MACROS
#define BREAKPOINT3
-#define ACPI_DISABLE_IRQS() __cli()
-#define ACPI_ENABLE_IRQS() __sti()
+#define ACPI_DISABLE_IRQS() local_irq_disable()
+#define ACPI_ENABLE_IRQS() local_irq_enable()
#define ACPI_FLUSH_CPU_CACHE() wbinvd()
:"=r"(n_hi), "=r"(n_lo) \
:"0"(n_hi), "1"(n_lo))
+/*
+ * Refer Intel ACPI _PDC support document for bit definitions
+ */
+#define ACPI_PDC_EST_CAPABILITY_SMP 0xa
+#define ACPI_PDC_EST_CAPABILITY_MSR 0x1
#ifdef CONFIG_ACPI_BOOT
extern int acpi_lapic;
extern int acpi_strict;
extern int acpi_disabled;
extern int acpi_ht;
-static inline void disable_acpi(void) { acpi_disabled = 1; acpi_ht = 0; }
+extern int acpi_pci_disabled;
+static inline void disable_acpi(void)
+{
+ acpi_disabled = 1;
+ acpi_ht = 0;
+ acpi_pci_disabled = 1;
+ acpi_noirq = 1;
+}
/* Fixmap pages to reserve for ACPI boot-time tables (see fixmap.h) */
#define FIX_ACPI_PAGES 4
-#else /* !CONFIG_ACPI_BOOT */
-# define acpi_lapic 0
-# define acpi_ioapic 0
-
-#endif /* !CONFIG_ACPI_BOOT */
+extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq);
-#ifdef CONFIG_ACPI_PCI
-static inline void acpi_noirq_set(void) { acpi_noirq = 1; }
-extern int acpi_irq_balance_set(char *str);
-#else
-static inline void acpi_noirq_set(void) { }
-static inline int acpi_irq_balance_set(char *str) { return 0; }
-#endif
+#ifdef CONFIG_X86_IO_APIC
+extern int skip_ioapic_setup;
+extern int acpi_skip_timer_override;
-#ifdef CONFIG_ACPI_SLEEP
+extern void check_acpi_pci(void);
-extern unsigned long saved_eip;
-extern unsigned long saved_esp;
-extern unsigned long saved_ebp;
-extern unsigned long saved_ebx;
-extern unsigned long saved_esi;
-extern unsigned long saved_edi;
+static inline void disable_ioapic_setup(void)
+{
+ skip_ioapic_setup = 1;
+}
-static inline void acpi_save_register_state(unsigned long return_point)
+static inline int ioapic_setup_disabled(void)
{
- saved_eip = return_point;
- asm volatile ("movl %%esp,(%0)" : "=m" (saved_esp));
- asm volatile ("movl %%ebp,(%0)" : "=m" (saved_ebp));
- asm volatile ("movl %%ebx,(%0)" : "=m" (saved_ebx));
- asm volatile ("movl %%edi,(%0)" : "=m" (saved_edi));
- asm volatile ("movl %%esi,(%0)" : "=m" (saved_esi));
+ return skip_ioapic_setup;
}
-#define acpi_restore_register_state() do {} while (0)
+#else
+static inline void disable_ioapic_setup(void) { }
+static inline void check_acpi_pci(void) { }
+#endif
+
+#else /* CONFIG_ACPI_BOOT */
+# define acpi_lapic 0
+# define acpi_ioapic 0
+
+#endif
+
+static inline void acpi_noirq_set(void) { acpi_noirq = 1; }
+static inline int acpi_irq_balance_set(char *str) { return 0; }
+
+#ifdef CONFIG_ACPI_SLEEP
/* routines for saving/restoring kernel state */
extern int acpi_save_state_mem(void);
extern unsigned long acpi_wakeup_address;
-extern void do_suspend_lowlevel_s4bios(int resume);
-
/* early initialization routine */
extern void acpi_reserve_bootmem(void);
#endif /*CONFIG_ACPI_SLEEP*/
+extern u8 x86_acpiid_to_apicid[];
+
#endif /*_ASM_ACPI_H*/
*/
struct kernel_param {
const char *name;
- enum { OPT_STR, OPT_UINT, OPT_UINT_UNIT, OPT_BOOL } type;
+ enum { OPT_STR, OPT_UINT, OPT_BOOL, OPT_CUSTOM } type;
void *var;
unsigned int len;
};
extern struct kernel_param __setup_start, __setup_end;
+#define custom_param(_name, _var) \
+ static char __setup_str_##_var[] __initdata = _name; \
+ static struct kernel_param __setup_##_var __attribute_used__ \
+ __initsetup = { __setup_str_##_var, OPT_CUSTOM, &_var, 0 }
#define boolean_param(_name, _var) \
static char __setup_str_##_var[] __initdata = _name; \
static struct kernel_param __setup_##_var __attribute_used__ \
static char __setup_str_##_var[] __initdata = _name; \
static struct kernel_param __setup_##_var __attribute_used__ \
__initsetup = { __setup_str_##_var, OPT_UINT, &_var, sizeof(_var) }
-#define integer_unit_param(_name, _var) \
- static char __setup_str_##_var[] __initdata = _name; \
- static struct kernel_param __setup_##_var __attribute_used__ \
- __initsetup = { __setup_str_##_var, OPT_UINT_UNIT, &_var, sizeof(_var) }
#define string_param(_name, _var) \
static char __setup_str_##_var[] __initdata = _name; \
static struct kernel_param __setup_##_var __attribute_used__ \
__attribute__ ((format (printf, 3, 4)));
extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
-long simple_strtol(const char *cp,char **endp,unsigned int base);
-unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base);
-long long simple_strtoll(const char *cp,char **endp,unsigned int base);
+long simple_strtol(
+ const char *cp,char **endp, unsigned int base);
+unsigned long simple_strtoul(
+ const char *cp,char **endp, unsigned int base);
+long long simple_strtoll(
+ const char *cp,char **endp, unsigned int base);
+unsigned long long simple_strtoull(
+ const char *cp,char **endp, unsigned int base);
+
+unsigned long long memparse(char *s);
#endif /* __LIB_H__ */